package controller.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import pojos.common.ImgAuthCode;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 图片验证码控制器
 */
@Controller
public class ImgAuthCodeController {

    private final Logger logger = LoggerFactory.getLogger(ImgAuthCodeController.class);

    /**
     * 生成随机数
     */
    private Random random = new Random();

    /**
     * 图片宽、图片高
     */
    private int width = 70;
    private int height = 35;

    /**
     * 字体
     */
    private String[] fontNames  = {"宋体", "Segoe Print", "Roman", "MV Boli", "Ink Free", "Chiller"};

    /**
     * 字符
     */
    private String codes  = "23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";

    /**
     * 背景色
     */
    private Color bgColor  = new Color(255, 255, 255);

    /**
     * 验证码字符个数
     */
    private int codeNum = 4;

    /**
     * 干扰线条数
     */
    private int disturbNum = 4;

    @GetMapping("/utils/imageAuthCode")
    public void getImage(HttpServletRequest request, HttpServletResponse response){
        HttpSession session = request.getSession();

        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = image.createGraphics();

        // 验证码背景色
        graphics.setColor(bgColor);
        graphics.fillRect(0,0,width,height);

        StringBuilder stringBuilder = new StringBuilder();

        // 向图片中画字符
        for(int i=0; i<codeNum; i++){
            // 随机字体
            String code = randomChar() + "";
            // 字体缓存
            stringBuilder.append(code);

            // 设置字符位置
            float x = i * 1.0f * width / 4;

            // 设置随机字体
            graphics.setFont(randomFont());

            // 设置随机颜色
            graphics.setColor(randomColor());

            // 画出字体
            graphics.drawString(code,x,height - 5);
        }

        // 生成干扰线
        for(int i=0; i<disturbNum; i++){
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int x2 = random.nextInt(width);
            int y2 = random.nextInt(height);

            graphics.setStroke(new BasicStroke(1.5f));
            graphics.setColor(randomColor());
            graphics.drawLine(x1,y1,x2,y2);
        }

        // 设置Session
        ImgAuthCode imgAuthCode = new ImgAuthCode();
        imgAuthCode.setAuthCode(stringBuilder.toString());
        imgAuthCode.setGenerateTime(System.currentTimeMillis());
        session.setAttribute("ImgAuthCode",imgAuthCode);

        try{
            ServletOutputStream outputStream = response.getOutputStream();
            // 响应类型格式
            response.setContentType("image/jpeg");
            // 禁止图像缓存
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", -1);

            // 输出图片
            ImageIO.write(image,"JPEG",outputStream);

            outputStream.flush();
            outputStream.close();
            response.flushBuffer();
        }catch (Exception e){
            e.printStackTrace();
            logger.error("生成图片验证码出错");
        }finally {
            graphics.dispose();
            image = null;
        }
    }

    /**
     * 生成随机颜色
     */
    private Color randomColor () {
        int red = random.nextInt(150);
        int green = random.nextInt(150);
        int blue = random.nextInt(150);
        return new Color(red, green, blue);
    }

    /**
     * 生成随机字体
     */
    private Font randomFont () {
        int index = random.nextInt(fontNames.length);

        //生成随机的字体名称
        String fontName = fontNames[index];

        //生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
        int style = random.nextInt(4);

        //生成随机字号, 24 ~ 28
        int size = random.nextInt(5) + 24;

        return new Font(fontName, style, size);
    }

    /**
     * 生成随机字符
     */
    private char randomChar () {
        int index = random.nextInt(codes.length());
        return codes.charAt(index);
    }
}
